#pragma once

namespace IDK
{
	template <typename T, typename _Self> 
	public ref class ManagedArray : public ManagedObject, public IEnumerable
	{
	public:
		typedef UnManaged::System::TArray<UnManaged::System::ref<_Self>> Self;
	public:

		ManagedArray(Self* self) : ManagedObject(mSelf = self)
		{
		}

		T^ Get(int index)
		{
			return gcnew T(mSelf->Get(index).GetUnmanagedPointer());
		}

		int Length(void)
		{
			return mSelf->Length();
		}

		ref class Enumerator : public IEnumerator
		{
		private:
			ManagedArray^ mContainer;
			int mIndex;
		public:
			Enumerator(ManagedArray^ container) 
				: mContainer(container)
			{
				mIndex = -1;
			}

			virtual property Object^ Current
			{
				Object^ get()
				{
					return mContainer->Get(mIndex);
				}
			}

			virtual bool MoveNext()
			{
				return ++mIndex < (int)mContainer->Length();
			}

			virtual void Reset()
			{
				mIndex = -1;
			}
		};

		virtual IEnumerator^ GetEnumerator(void)
		{
			return gcnew Enumerator(this);
		}
	private:
		Self* mSelf;
	};
}